package server;

/**
* Simple HTTP server
* @author kishore@Acesurf
* @version 1.2   
*/

import java.io.*;
import java.net.*;
import java.util.*;


public class Server extends Thread {

    ServerSocket listen_socket;
    String httpRootDir;
    
    public Server(String port, String httpRoot) {
        try {
            // set instance variables from constructor args
            int servPort = Integer.parseInt(port);
            httpRootDir = httpRoot;

            // create new ServerSocket
            listen_socket = new ServerSocket(servPort);

        } catch (IOException e) {
            System.err.println(e);
        }

        // Start running Server thread
        this.start();
    }

    @Override
    public void run() {
        try {
            while (true) {
                // listen for a request. When a request comes in,
                // accept it, then create a Connection object to
                // service the request and go back to listening on
                // the port.

                Socket client_socket = listen_socket.accept();
//                /System.out.println("connection request received");
                @SuppressWarnings("unused")
				Connection c = new Connection(client_socket, httpRootDir);
            }
        } catch (IOException e) {
            System.err.println(e);
        }
    }

    public static void start(int port, String rootDir) {
        

        new Server("" + port,rootDir);
    }
}

// The Connection class -- this is where HTTP requests are serviced

class Connection extends Thread {
    protected Socket client;
    protected BufferedReader in;
    protected PrintStream out;
    String httpRootDir;
    String requestedFile;

    public Connection(Socket client_socket, String httpRoot) 
    {
        // set instance variables from args
        httpRootDir = httpRoot;
        client = client_socket;
        
        // create input and output streams for conversation with client
        
        try {
            in = new BufferedReader(new InputStreamReader(new DataInputStream(client.getInputStream())));
            out = new PrintStream(client.getOutputStream());
            System.out.println("Accepted request from client: "+client.getRemoteSocketAddress());
        } catch (IOException e) {
            System.err.println(e);
            try {
                client.close();
            } catch (IOException e2) {
            }
            return;
        }
        // start this object's thread -- the rest of the action
        // takes place in the run() method, which is called by
        // the thread.
        this.start();

    }

    @Override
    public void run() {

        String line = null; // read buffer
        String req = null; // first line of request
        // OutputStream os;

        try {
            // read HTTP request -- the request comes in
            // on the first line, and is of the form:
            // GET <filename> HTTP/1.x

            req = in.readLine();

            // loop through and discard rest of request
            line = req;
            while (line.length() > 0) {
                line = in.readLine();
            }

            // parse request -- get filename
            StringTokenizer st = new StringTokenizer(req);
            // discard first token ("GET")
            st.nextToken();
            requestedFile = st.nextToken().replace("%20", " ");
            


            
            ///-------This is just for a test , can remove it after testing-------
            if (requestedFile.contains("/test"))
            {
                sendResponseHeader("text/html");
                String searchResult = "<h1>Acesurf HTTP server v1.1 Test Page</h1>";
                
                if (searchResult != null)
                    sendString(searchResult);
                else
                    sendString("No Page");

                return;
            }

            // create File object
            File f = new File(httpRootDir + requestedFile);
            
            
            // check to see if file exists
            if (!f.canRead()) {
                sendResponseHeader("text/html");
                sendString("<h1>Acesurf HTTP server v1.1</h1><H2>404: requested page \""+requestedFile+"\" not found</h2>");
                return;
            }
            

            if(f.isDirectory())
            {      
                if(requestedFile.charAt(requestedFile.length()-1) != '/' && requestedFile.length() > 1)
                        requestedFile+="/";
                f = new File(httpRootDir + requestedFile+"index.html");                
            }

            System.out.println(httpRootDir + requestedFile);
            
            sendFile(f);
            
        } catch (IOException e) {
            System.out.println("2"+e);
        } finally {
            try {
                client.close();
            } catch (IOException e) {
            }
            

        }

    }

    void sendFile(File f) 
    {
    	//-------------Set your MIME types-----------
    	
    	FileNameMap fileNameMap = URLConnection.getFileNameMap();
		String mimeType = fileNameMap.getContentTypeFor(f.getName());
		//System.out.println("mimeType="+ mimeType);
		if(mimeType.equalsIgnoreCase("text/html"))
		sendResponseHeader(mimeType);
		
		//-------------
		try {
			FileInputStream fis = new FileInputStream(f);
			BufferedInputStream fileI=new BufferedInputStream(fis);
			byte[] b=new byte[1000];
			while (true)
            {
                int len = fileI.read(b);
                if(len==1000)
                    out.write(b);
                else
                {
                    for(int l = 0 ; l < len; l++ )
                    {
                        out.write(b[l]);
                    }
                    break;
                }
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

    // send a HTTP header to the client
    // The first line is a status message from the server to the client.
    // The second line holds the mime type of the document
    void sendResponseHeader(String type) {
        out.println("HTTP/1.0 200 OK");
        out.println("Content-type: " + type + "\n\n");
    }

    // write a string to the client.
    void sendString(String str) {
        out.print(str);
    }        
  
}